package com.iris.live.services.services.impl;

import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.JsonObject;
import com.iris.live.services.common.*;
import com.iris.live.services.common.reconsitution.MessageContext;
import com.iris.live.services.data.models.*;
import com.iris.live.services.data.repositories.*;
import com.iris.live.services.data.specifications.MarketSpecifications;
import com.iris.live.services.data.specifications.SpecificationUtils;
import com.iris.live.services.models.PageData;
import com.iris.live.services.models.ResultData;
import com.iris.live.services.services.MarketService;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.Assert;

import java.io.InputStream;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by sxy on 2016/7/11.
 */
@SuppressWarnings("SpringJavaAutowiringInspection")
@Service
@Transactional//(readOnly = true)
public class MarketServiceImpl implements MarketService {
    private static org.slf4j.Logger logger = LoggerFactory.getLogger(MarketServiceImpl.class);

    @Autowired
    private MarketRepository marketRepository;

    @Autowired
    private Lsh活动表Repository lsh活动表Repository;

    @Autowired
    private Lsh集团消息Repository lsh集团消息Repository;

    @Autowired
    private 邀约跟进记录表Repository 邀约跟进记录表Repository;

    @Autowired
    private 顾客记录汇总Repository 顾客记录汇总Repository;

    @Autowired
    private Lsh车型Repository lsh车型Repository;

    @Autowired
    private 用户Repository 用户Repository;

    @Autowired
    private FileRepository fileRepository;

    @Autowired
    private Lsh导入名单Repository lsh导入名单Repository;

    @Autowired
    private Lsh市场设置Repository lsh市场设置Repository;

    @Autowired
    private Lsh活动推送岗位Repository lsh活动推送岗位Repository;

    @Autowired
    private Lsh活动推送Repository lsh活动推送Repository;

    @Autowired
    private Lsh导入名单联系表Repository lsh导入名单联系表Repository;

    @Autowired
    private 预约信息表Repository 预约信息表Repository;

    @Autowired
    private 报价单表Repository 报价单表Repository;

    @Autowired
    private DictionaryRepository dictionaryRepository;

    @Autowired
    private Lsh活动KpiRepository lsh活动KpiRepository;

    @Autowired
    private Lsh活动类型附属repository lsh活动类型附属repository;

    @Autowired
    private Lsh活动类型Repository lsh活动类型Repository;

    @Autowired
    private Lsh活动目标Repository lsh活动目标Repository;

    @Autowired
    private 顾客进店记录表Repository repository顾客进店记录表;

    @Autowired
    private Itask基础设置Repository itask基础设置Repository;

    @Autowired
    private TDccDistributionLogRepository tDccDistributionLogRepository;

    @Autowired
    private Lsh待办事项Repository lsh待办事项Repository;


    @Override
    public PageData getActionList(String permit, GetActionListRequest request) {
        request = MoreObjects.firstNonNull(request, new GetActionListRequest());
        return this.marketRepository.getActionList(request.getPageSize(), request.getPageIndex(), permit,
                request.code, request.name, request.level, request.type, request.startBefore, request.endAfter, request.actionCode, request.starter);
    }

    @Override
    public Object getActionInfoByID(int id) {
        return this.marketRepository.getActionInfoByID(id);
    }

    @Override
    @Transactional
    public boolean saveActionInfoStatus(int id, String status) {
        int result = this.lsh活动表Repository.set启用状态By活动编号(id, status);
        return result > 0;
    }

    @Override
    @Transactional
    public Lsh活动表Model delActionByID(int id) {
        Lsh活动表Model model = this.lsh活动表Repository.findOne(id);
        Assert.notNull(model);

        model.set启用状态("已删除");
        return this.lsh活动表Repository.save(model);

    }

    @Override
    public List<用户Model> getEmployeeList(String license) {
        return this.用户Repository.findAll(MarketSpecifications.isUserLicenseEqual(license));
    }

    @Override
    public List<String> getCustomerSource(String source) {
        List<顾客记录汇总Model> list = this.顾客记录汇总Repository.findAll(MarketSpecifications.isCustomerLogChannelEqual(source));
        return FluentIterable
                .from(list)
                .transform(item -> item.get顾客渠道())
                .toList();
    }

    @Override
    @Transactional
    public Object saveActionInvite(Object invite) {
        throw new NotImplementedException("TODO");
    }

    @Override
    @Transactional
    public String saveLeaflets(Lsh集团消息Model request, Pair<InputStream, String> file) {
//        Lsh集团消息Model model = this.lsh集团消息Repository.findOne(request.get信息编号());
//        Assert.notNull(model);

//        model.set宣传页路径(this.fileRepository.save(file.getLeft(), file.getRight()));
//        return this.lsh集团消息Repository.save(model);
        return this.fileRepository.save(file.getLeft(), file.getRight());
    }

    @Override
    public String getLeaflets(Lsh集团消息Model request) {
        Lsh集团消息Model model = this.lsh集团消息Repository.findOne(request.get信息编号());
        Assert.notNull(model);
        Assert.isTrue(!Strings.isNullOrEmpty(model.get宣传页路径()));

        return model.get宣传页路径();
    }

    @Override
    @Transactional
    public Lsh集团消息Model saveActionContent(Lsh集团消息Model request) {
        return this.lsh集团消息Repository.save(request);
    }

    @Override
    @Transactional
    public Lsh集团消息Model updatePolicyFile(Lsh集团消息Model request, Pair<InputStream, String> file) {
        Lsh集团消息Model model = this.lsh集团消息Repository.findOne(request.get信息编号());
        Assert.notNull(model);

        model.set附件路径(this.fileRepository.save(file.getLeft(), file.getRight()));
        return this.lsh集团消息Repository.save(model);
    }

    @Override
    public List<String> getDealerList() {
        List<Lsh活动表Model> list = this.lsh活动表Repository.findAll();
        return FluentIterable
                .from(list)
                .transform(item -> item.get活动代码())
                .toList();
    }

    @Override
    @Transactional
    public Lsh活动表Model saveActionInfo(Lsh活动表Model request) {
        return this.lsh活动表Repository.save(request);
    }

    @Override
    @Transactional
    public List<Lsh活动推送Model> saveActionPush(List<Lsh活动推送Model> modelList) {
        List<Lsh活动推送Model> list = new ArrayList<>();
        if (modelList.size() > 0) {
            for (int i = 0; i < modelList.size(); i++) {
                Assert.notNull(modelList.get(i));
                Integer activityId = modelList.get(i).get活动编号();
                //先删除活动编号的所有推送
                List<Lsh活动推送Model> oldlist = lsh活动推送Repository.findByCode(activityId);
                if (oldlist.size() > 0) {
                    for (int m = 0; m < oldlist.size(); m++) {
                        lsh活动推送Repository.delete(oldlist.get(m));
                    }
                }
                Lsh活动推送Model m = this.lsh活动推送Repository.save(modelList.get(i));
                list.add(m);
            }
        }
        return list;
    }

    @Override
    public List<邀约跟进记录表Model> outputInvite() {
        return this.邀约跟进记录表Repository.findAll();
    }

    @Override
    @Transactional
    public 邀约跟进记录表Model saveOutputInvite(邀约跟进记录表Model model) {
        Assert.notNull(model);
        return this.邀约跟进记录表Repository.save(model);
    }

    @Override
    @Transactional
    public List<邀约跟进记录表Model> saveOutputInviteBatch(List<邀约跟进记录表Model> modelList) {
        Assert.notNull(modelList);
        return this.邀约跟进记录表Repository.save(modelList);
    }

    @Override
    public List<Lsh车型Model> getCarType(Lsh车型Model request) {
        Example<Lsh车型Model> qbe = Example.of(request);
        return this.lsh车型Repository.findAll(qbe);
    }

    @Override
    public Page<Lsh导入名单Model> getInputList(String permit, GetInputListRequest request) {
        Pageable page = new PageRequest(request.getPageIndex(), request.getPageSize());
        List<Specification<Lsh导入名单Model>> specs = Lists.newArrayList();
        if (!Strings.isNullOrEmpty(request.name)) {
            specs.add(MarketSpecifications.likeUserName导入名单(request.name));
        }

        if (!Strings.isNullOrEmpty(request.phone)) {
            specs.add(MarketSpecifications.likeUserPhone导入名单(request.phone));
        }

        if (!Strings.isNullOrEmpty(request.type)) {
            specs.add(MarketSpecifications.isSource导入名单(request.type));
        }

        if (request.endAfter != null) {
            specs.add(MarketSpecifications.isBookingsEndAfter导入名单(request.endAfter));
        }

        if (!Strings.isNullOrEmpty(request.series)) {
            specs.add(MarketSpecifications.is车型车系Equal导入名单(request.series));
        }

        if (!Strings.isNullOrEmpty(request.model)) {
            specs.add(MarketSpecifications.is车型车型Equal导入名单(request.model));
        }

        return this.lsh导入名单Repository.findAll(SpecificationUtils.andAllOrNull(specs), page);
    }

    @Override
    public Lsh导入名单Model getInputList(int id, String account) {
        Lsh导入名单Model model = this.lsh导入名单Repository.findOne(id);
        if (model.get所属CDO() == null || "".equals(model.get所属CDO())) {
            model.set所属CDO(account);
            if ("".equals(model.get是否置换())) {
                model.set是否置换(null);
            }
            if (StringUtils.isNullOrBlank(model.get顾客性别())) {
                model.set顾客性别("男");
            }
            if ("".equals(model.get是否同行())) {
                model.set是否同行(null);
            }
            if ("".equals(model.get是否评估())) {
                model.set是否评估(null);
            }
            if ("".equals(model.get是否试驾())) {
                model.set是否试驾(null);
            }
            if ("".equals(model.get是否金融())) {
                model.set是否金融(null);
            }
            if ("".equals(model.get是否线索())) {
                model.set是否线索("否");
            }
            if ("".equals(model.get是否有效线索())) {
                model.set是否有效线索("否");
            }
            return lsh导入名单Repository.save(model);
        }
        return model;
    }

    @Override
    @Transactional
    public Lsh导入名单Model addInputList(Lsh导入名单Model request) {
        if (request != null) {
            //DCC分配线索给sc，将sc认领状态置null
            request.setClaimState(null);
            request = this.lsh导入名单Repository.save(request);
            if (!StringUtils.isNullOrBlank(request.get所属销售顾问())) {
                saveImportListOtherWork(request);
            }
        }
        return request;
    }

    //DCC分配线索给销售顾问超时时间，并发送消息通知销售顾问
    private void saveImportListOtherWork (Lsh导入名单Model lsh导入名单Model) {
        Itask基础设置ModelPK itask基础设置ModelPK = new Itask基础设置ModelPK();
        itask基础设置ModelPK.set许可(lsh导入名单Model.get许可());
        itask基础设置ModelPK.set设置项目("CLUE_DISTRIBUTION_OVERDUE");
        Itask基础设置Model itask基础设置Model = itask基础设置Repository.findOne(itask基础设置ModelPK);
        String value = null;
        //DCC分配线索给销售顾问，判断是否设置线索分配超时时间，未设置则默认为 3
        if (itask基础设置Model == null) {
            value = "3";
        } else {
            value = itask基础设置Model.get值();
        }
        //DCC分配线索给销售顾问，判断线索分配超时时间是否合法，不合法则默认为 3
        if (!StringUtils.isNumeric(value)) {
            value = "3";
        }
        //添加DCC分配超时记录
        //可能存在DCC重复操作或将线索分配给其他sc，所以先判断是否已经存在该 导入编号的记录
        logger.info("查询可能存在的DCC分配记录，导入编号:" + lsh导入名单Model.get导入编号());
        List<TDccDistributionLogModel> logModels = tDccDistributionLogRepository.getModelByImportId(lsh导入名单Model.get导入编号());
        if (logModels != null) {
            tDccDistributionLogRepository.delete(logModels);
        }
        TDccDistributionLogModel t = new TDccDistributionLogModel();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR_OF_DAY, Integer.parseInt(value));
        t.setImportId(lsh导入名单Model.get导入编号());
        t.setOverdueTime(new Timestamp(calendar.getTime().getTime()));
        logger.info("DCC分配线索给销售顾问，记录线索分配超时时间");
        tDccDistributionLogRepository.save(t);
        //推送消息给sc
        String msg = MessageContext.getDCCDistributionClueMessage(lsh导入名单Model.get顾客姓名());
        LshMsgUtils.getLshMsg(lsh导入名单Model.get许可(), lsh导入名单Model.get所属CDO(), lsh导入名单Model.get许可(),
                lsh导入名单Model.get所属销售顾问(),"线索", msg, lsh导入名单Model.get所属CDO(), lsh导入名单Model.get电话号码());
        //极光推送
        JsonObject jsonObject = JsonObjectUtils.getJsonObject("线索", null, null, lsh导入名单Model.get电话号码(), null, lsh导入名单Model.get所属销售顾问());
        List list = new ArrayList();
        list.add(lsh导入名单Model.get所属销售顾问());
        JPush.sendPushForAndroidAndIos(msg, msg, jsonObject, list, JPush.Platforms.iTask);
    }

    @Override
    @Transactional
    public List<Lsh导入名单Model> addInputListBatch(List<Lsh导入名单Model> modelList) {
        return this.lsh导入名单Repository.save(modelList);
    }

    @Override
    public List<Lsh市场设置Model> getMarketSetList() {
        return this.lsh市场设置Repository.findAll();
    }

    @Override
    public Lsh市场设置Model getMarketSetList(int MarketID) {
        return this.lsh市场设置Repository.findOne(MarketID);
    }

    @Override
    @Transactional
    public Lsh市场设置Model addMarketSet(Lsh市场设置Model request) {
        return this.lsh市场设置Repository.save(request);
    }

    @Override
    @Transactional
    public Lsh活动目标Model saveActionTarget(Lsh活动目标Model request) {
        return this.lsh活动目标Repository.save(request);
    }

    @Override
    public Lsh活动目标Model getActionTarget(int actionID) {
        //this.lsh活动目标Repository.findOne(actionID);
        return null;
    }

    @Override
    public List<Lsh集团消息Model> getActionContentByCarType(int carType) {
        return this.lsh集团消息Repository.findAll(MarketSpecifications.is消息车型Equal集团消息(carType));
    }

    @Override
    public Page<Lsh集团消息Model> getActionInfoList(String permit, GetActionInfoList request) {
        Pageable page = new PageRequest(request.getPageIndex(), request.getPageSize());
        List<Specification<Lsh集团消息Model>> specs = Lists.newArrayList();
        if (!Strings.isNullOrEmpty(request.name)) {
            specs.add(MarketSpecifications.likeNameEqual集团消息(request.name));
        }
        if (!Strings.isNullOrEmpty(request.department)) {
            specs.add(MarketSpecifications.isDepartmentEqual集团消息(request.department));
        }

        if (!Strings.isNullOrEmpty(request.type)) {
            specs.add(MarketSpecifications.isTypeEqual集团消息(request.type));
        }
        if (request.startBefore != null) {
            specs.add(MarketSpecifications.isDateEndBefore集团消息(request.startBefore));
        }
        if (request.endAfter != null) {
            specs.add(MarketSpecifications.isDateEndAfter导入名单(request.endAfter));
        }

        return this.lsh集团消息Repository.findAll(SpecificationUtils.andAllOrNull(specs), page);
    }

    @Override
    public List getActionPosts(int actionID) {
        return marketRepository.getActionPosts(actionID);
    }

    @Override
    public List getAppointment(String actionID) {
        return marketRepository.getAppointment(actionID);
    }

    @Override
    @Transactional
    public List<Lsh活动推送岗位Model> savePushJobBatch(int id, List<Lsh活动推送岗位Model> modelList) {
        this.lsh活动推送岗位Repository.delBy活动编号(id);
        List<Lsh活动推送岗位Model> result = this.lsh活动推送岗位Repository.save(modelList);
        return result;
    }

    @Override
    public List<Lsh活动推送岗位Model> getPushJob(int id) {
        return this.lsh活动推送岗位Repository.findBy活动编号(id);
    }

    @Override
    public 顾客记录汇总Model getCustomerLog(int id) {
        return this.顾客记录汇总Repository.findOne(id);
    }

    @Override
    public 顾客记录汇总Model saveCustomerLog(顾客记录汇总Model model) {
        Assert.notNull(model);
        return this.顾客记录汇总Repository.save(model);
    }

    @Override
    public Lsh导入名单联系表Model getInputRelation(int id,String permit) {
        return this.lsh导入名单联系表Repository.findOne(MarketSpecifications.isInputID(id,permit));
    }

    @Override
    public Lsh导入名单联系表Model saveInputRelation(Lsh导入名单联系表Model model) {
        Assert.notNull(model);
        return this.lsh导入名单联系表Repository.save(model);
    }

    @Override
    public 预约信息表Model getReservation(int id) {
        return this.预约信息表Repository.findOne(id);
    }

    @Override
    public 预约信息表Model saveReservation(预约信息表Model model) {
        Assert.notNull(model);
        return this.预约信息表Repository.save(model);
    }

    @Override
    public List getActionTypesList() {
        return this.dictionaryRepository.getLSH活动类型List();
    }

    @Override
    public List getActionStarterList() {
        return this.dictionaryRepository.getLSH活动发起设置List();
    }

    @Override
    public List getMarketSetType(String permission, String channel) {
        return this.marketRepository.getMarketSetType(permission, channel);
    }

    @Override
    public List getMarketSetSource(String permission, String channel, String type) {
        return this.marketRepository.getMarketSetSource(permission, channel, type);
    }

    @Override
    public List getActionByCar(String permission,  List <String> list ) {
        return this.marketRepository.getActionByCar(permission, list);
    }

    @Override
    public PageData getCustomerRecords(String permit, GetCustomerRecords request) {
        return this.marketRepository.getCustomerRecords(permit, request);
    }

    @Override
    public Map getCustomerRecordsInfo(GetCustomerRecords request) {
        return this.marketRepository.getCustomerRecordsInfo(request);
    }

    @Override
    public Object findInputListByPhone(String phone) {
        return this.marketRepository.findInputListByPhone(phone);
    }

    @Override
    public Lsh导入名单Model getInputList(String phone, String account, String permit) {
        //查找最新的一条记录
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -2);
        Date dtTime = DateFormatUtils.getFormatDate("yyyy-MM-01", c.getTime());//3个自然月前
        java.sql.Date sqlDt = new java.sql.Date(dtTime.getTime());
        //三个月内有效线索
        List<Lsh导入名单Model> list = this.lsh导入名单Repository.findByPhoneAndPermitAndTimeDesc1(phone, permit, dtTime);
        //查询顾客记录汇总
        顾客记录汇总Model old汇总 = 顾客记录汇总Repository.findCusByPhoneAndPermit(phone, permit);
        List<顾客进店记录表Model> list进店 = new ArrayList<>();
        if (list.size() == 0) {
            return null;
        }
        if (old汇总 != null) {
            list进店 = repository顾客进店记录表.findBy进店日期And许可(old汇总.get顾客编号(), permit, list.get(0).get线索创建日期());

        }
        if (list.size() > 0 && list进店.size() == 0) {
            Lsh导入名单Model model = list.get(0);
            if (model.get所属CDO() == null || "".equals(model.get所属CDO())) {
                model.set所属CDO(account);
                if ("".equals(model.get是否置换())) {
                    model.set是否置换(null);
                }
                if ("".equals(model.get顾客性别())) {
                    model.set顾客性别("男");
                }
                if ("".equals(model.get是否同行())) {
                    model.set是否同行(null);
                }
                if ("".equals(model.get是否评估())) {
                    model.set是否评估(null);
                }
                if ("".equals(model.get是否试驾())) {
                    model.set是否试驾(null);
                }
                if ("".equals(model.get是否金融())) {
                    model.set是否金融(null);
                }
                if ("".equals(model.get是否线索())) {
                    model.set是否线索("否");
                }
                if ("".equals(model.get是否有效线索())) {
                    model.set是否有效线索("否");
                }
                return lsh导入名单Repository.save(model);
            }
            return model;
        }
        return null;

    }

    @Override
    public int getTaskCompleteCount(String permission, String customer) {
        return this.marketRepository.getTaskCompleteCount(permission, customer);
    }

    @Override
    public List getSaleListByCustomer(int customerID) {
        return this.marketRepository.getSaleListByCustomer(customerID);
    }

    @Override
    public List getPassengerFlowLogByCustomer(int customerID) {
        return this.marketRepository.getPassengerFlowLogByCustomer(customerID);
    }

    @Override
    public List getActionIDList(int id) {
        return this.marketRepository.getActionIDList(id);
    }

    @Override
    public Object getOrderStatus(int customer) {
        return this.marketRepository.getOrderStatus(customer);
    }

    @Override
    public List getOrderStatusList(int customer) {
        return this.marketRepository.getOrderStatusList(customer);
    }

    @Override
    public Map getCustomerIDFromRecords(String customer, String sale) {
        return this.marketRepository.getCustomerIDFromRecords(customer, sale);
    }

    @Override
    public List getCompetingList() {
        return this.marketRepository.getCompetingList();
    }


    @Override
    @Transactional
    public boolean saveStatusByCustomerId(int customerId, String status) {
        报价单表Model model = this.报价单表Repository.findBy顾客编号(customerId);
        if (model == null) {
            return false;
        }

        int result = this.报价单表Repository.set当前状态By报价编号(model.get报价编号(), status);
        return true;
    }

    @Override
    public List getCompetingListByBrand(String brand) {
        return this.marketRepository.getCompetingListByBrand(brand);
    }

    @Override
    public PageData getGetActKPIList(GetGetActKPIListReq req) {
        return marketRepository.getGetActKPIList(req);
    }

    @Override
    @Transactional
    public boolean updateActKPIStatus(GetGetActKPIListReq req) {
        try {
            lsh活动KpiRepository.updateStatusById(Integer.valueOf(req.KPI编号), req.启用状态);
            return true;
        } catch (Exception e) {
            logger.error("系统异常。", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    @Override
    @Transactional
    public Map saveActKPIList(List<Lsh活动KpiModel> reqList) {
        Map map = Maps.newHashMap();
        int insertCount = 0;
        int updateCount = 0;
        Timestamp ts = DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date());
        for (int i = 0; i < reqList.size(); i++) {
            Lsh活动KpiModel m = reqList.get(i);
            //1.根据许可和kpi查询是否有记录
            List<Lsh活动KpiModel> list = lsh活动KpiRepository.isExsitActKPI(m.get许可(), m.getKpi());
            if (list.size() > 0) {
                //更新第一条
                Lsh活动KpiModel old = list.get(0);
                old.set更新时间(ts);
                if (m.getKpi定义() != null) {
                    old.setKpi定义(m.getKpi定义());
                }
                if (m.getKpi目的() != null) {
                    old.setKpi目的(m.getKpi目的());
                }
                if (m.getKpi公式() != null) {
                    old.setKpi公式(m.getKpi公式());
                }

                old.setKpi备注(m.getKpi备注());

                if (m.get更新账号() != null) {
                    old.set更新账号(m.get更新账号());
                }
                lsh活动KpiRepository.save(old);
                updateCount++;
            } else {
                m.set启用状态("启用");
                m.set创建时间(ts);
                m.set更新时间(ts);
                lsh活动KpiRepository.save(m);
                insertCount++;
            }
        }
        map.put("updateCount", updateCount);
        map.put("insertCount", insertCount);
        return map;
    }

    @Override
    public boolean isExsitActKPI(GetGetActKPIListReq req) {
        List<Lsh活动KpiModel> list = lsh活动KpiRepository.isExsitActKPI(req.许可, req.KPI);
        return list.size() > 0 ? true : false;
    }

    @Override
    public PageData getActRecommendKPIList(GetGetActKPIListReq req) {
        return marketRepository.getActRecommendKPIList(req);
    }

    @Override
    public boolean updateActivityStatus(GetGetActKPIListReq req) {
        try {
            Lsh活动类型Model m = lsh活动类型Repository.findOne(Integer.valueOf(req.活动类型编号));
            if (m != null) {
                m.set启用状态(req.启用状态);
                lsh活动类型Repository.save(m);
            }
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("系统异常。", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean saveActTargetKPIList(List<Lsh活动目标Model> reqList) {
        Timestamp ts = DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date());
        try {
            //根据活动编号删除所有活动
            if (reqList.size() > 0) {
                List<Lsh活动目标Model> oldList = lsh活动目标Repository.findByActCode(reqList.get(0).get活动编号());
                if (oldList.size() > 0) {
                    lsh活动目标Repository.delete(oldList);
                }
            }

            for (int i = 0; i < reqList.size(); i++) {
                Lsh活动目标Model m = reqList.get(i);
                m.set更新时间(ts);
            }
            if (reqList.size() > 0) {
                for (int j = 0; j < reqList.size(); j++) {
                    Lsh活动目标Model n = reqList.get(j);
                    if (n.getKpi编号() != null) {
                        lsh活动目标Repository.save(n);
                    }
                }
            }
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("系统异常。", e);
            return false;
        }

    }

    @Override
    @Transactional
    public boolean saveActRecommendKPI(List<GetGetActKPIListReq> reqList) {
        try {
            for (int i = 0; i < reqList.size(); i++) {
                //根据kpi编号和活动类型编号查询附属表
                GetGetActKPIListReq g = reqList.get(i);
                Lsh活动类型附属ModelPK pk = new Lsh活动类型附属ModelPK();
                pk.setKpi编号(g.KPI编号);
                pk.set活动类型编号(g.活动类型编号);
                Lsh活动类型附属Model model = lsh活动类型附属repository.findOne(pk);
                if (model != null) {
                    if (g.选择状态 == null) {
                        //删除
                        lsh活动类型附属repository.delete(model);
                    } else {
                        model.set选择状态(g.选择状态);
                        model.set更新账号(g.更新账号);
                        model.set更新时间(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
                        lsh活动类型附属repository.save(model);
                    }
                } else {
                    //新增
                    if (g.KPI编号 != null) {
                        Lsh活动类型附属Model l = new Lsh活动类型附属Model();
                        l.set选择状态(g.选择状态);
                        l.setKpi编号(g.KPI编号);
                        l.set活动类型编号(g.活动类型编号);
                        l.set更新时间(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
                        l.set更新账号(g.更新账号);
                        lsh活动类型附属repository.save(l);
                    }
                }
            }
            if (reqList.size() > 0) {
                GetGetActKPIListReq f = reqList.get(0);
                //根据活动类型编号，更新活动类型表
                Lsh活动类型Model mo = lsh活动类型Repository.findById(f.活动类型编号);
                //   Lsh活动类型Model mo = lsh活动类型Repository.findOne(g.活动类型编号);
                if (mo != null) {
                    //更新备注
                    mo.set更新账号(f.更新账号);
                    mo.set更新时间(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
                    mo.set备注(f.备注);
                    lsh活动类型Repository.save(mo);
                }
            }
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("系统异常。", e);
            return false;
        }
    }

    @Override
    public List getActAttachKPIList(GetGetActKPIListReq req) {
        return marketRepository.getActAttachKPIList(req);
    }

    @Override
    public Map getActKPI(GetActKPIReq req) {
        Map map = new HashMap();
        //获取邀约客户数
        List list邀约客户数 = marketRepository.find邀约客户数(req);
        map.put("邀约线索数", list邀约客户数.size());

        //达成邀约数
        List list达成邀约数 = marketRepository.find达成邀约数(req);
        map.put("达成邀约数", list达成邀约数.size());

        //实际出席总数
        List list实际出席总数 = marketRepository.find实际出席总数(req);
        map.put("实际出席总数", list实际出席总数.size());

        //邀约出席数
        List list邀约出席数 = marketRepository.find邀约出席数(req);
        map.put("邀约出席数", list邀约出席数.size());

        //非邀约出席数
        map.put("非邀约出席数", list实际出席总数.size() - list邀约出席数.size());

        //试乘试驾数
        List list试乘试驾数 = marketRepository.findRecordByParams(req, "是否试驾");
        map.put("试乘试驾数", list试乘试驾数.size());

        //二手车评估数
        List list二手车评估数 = marketRepository.findRecordByParams(req, "是否评估");
        map.put("二手车评估数", list二手车评估数.size());

        //报价数
        List list报价数 = marketRepository.findRecordByParams(req, "是否报价");
        map.put("报价数", list报价数.size());

        //订单数
        List list订单数 = marketRepository.find订单数(req);
        map.put("订单数", list订单数.size());

        //零售数
        List list零售数 = marketRepository.find零售数(req);
        map.put("零售数", list零售数.size());

        //新增线索数
        List list新增线索数 = marketRepository.find新增线索数(req);
        map.put("新增线索数", list新增线索数.size());

        //线索首次进店数
        List list线索首次进店数 = marketRepository.find线索首次进店数(req);
        map.put("线索首次进店数", list线索首次进店数.size());

        //线索再次进店数
        List list线索再次进店数 = marketRepository.find线索再次进店数(req);
        map.put("线索再次进店数", list线索再次进店数.size());

        DecimalFormat df = new DecimalFormat("####0.000000");
        //邀约成功率:达成邀约数÷邀约线索数x100%
        map.put("邀约成功率", list邀约客户数.size() == 0 ? 0 : df.format(Double.parseDouble(list达成邀约数.size() + "") / Double.parseDouble(list邀约客户数.size() + "")));

        //邀约出席率:邀约出席数÷达成邀约数x100%
        map.put("邀约出席率", list达成邀约数.size() == 0 ? 0 : df.format(Double.parseDouble(list邀约出席数.size() + "") / Double.parseDouble(list达成邀约数.size() + "")));

        //线索进店率:（线索首次进店数+线索再次进店数）÷邀约线索数x100%
        map.put("线索进店率", list邀约客户数.size() == 0 ? 0 : df.format(Double.parseDouble(list线索首次进店数.size() + list线索再次进店数.size() + "") / Double.parseDouble(list邀约客户数.size() + "")));
        return map;
    }

    @Override
    public ResultData getSignForm(GetActKPIReq req) {
        ResultData rd = new ResultData();
        try {
            List list = marketRepository.findSignFormList(req);
            rd.setResult("true");
            rd.setMessage("查询成功");
            rd.setPageData(new PageData(list, list.size()));
        } catch (Exception e) {
            logger.error("系统异常。", e);
            rd.setMessage("查询发生异常");
            rd.setResult("false");
            return rd;
        }
        return rd;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultData saveClueDistributionSetUp (String permit, String username, String value) throws Exception {
        ResultData resultData = new ResultData("false", null, null);
        if (!StringUtils.isNumeric(value)) {
            resultData.setMessage("线索分配超时设置值不合法");
            return resultData;
        }
        if (Integer.parseInt(value) <= 0) {
            resultData.setMessage("线索分配超时设置值必须大于0");
            return resultData;
        }
        logger.info("保存线索分配超时时间，许可：" + permit + ",value:" + value);
        Itask基础设置Model itask基础设置Model = saveClueDistributionOverdue(permit, username, value);
        List list = new ArrayList();
        list.add(itask基础设置Model);
        resultData.setResult("true");
        resultData.setPageData(new PageData(list, 1));
        return resultData;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultData getClueDistributionSetUp (String permit, String username) throws Exception {
        ResultData resultData = new ResultData("false", null, null);
        Itask基础设置ModelPK itask基础设置ModelPK = new Itask基础设置ModelPK();
        itask基础设置ModelPK.set许可(permit);
        itask基础设置ModelPK.set设置项目("CLUE_DISTRIBUTION_OVERDUE");
        Itask基础设置Model itask基础设置Model = itask基础设置Repository.findOne(itask基础设置ModelPK);
        if (itask基础设置Model == null) {
            logger.info("查询线索超时时间，经销商未设置，系统设置默认值： 3");
            itask基础设置Model = saveClueDistributionOverdue(permit, username, "3");
        }
        List list = new ArrayList();
        list.add(itask基础设置Model);
        resultData.setResult("true");
        resultData.setPageData(new PageData(list, list.size()));
        return resultData;
    }

    private Itask基础设置Model saveClueDistributionOverdue (String permit, String username, String value) {
        Itask基础设置Model itask基础设置Model = new Itask基础设置Model();
        itask基础设置Model.set许可(permit);
        itask基础设置Model.set设置项目("CLUE_DISTRIBUTION_OVERDUE");
        itask基础设置Model.set值(value);
        itask基础设置Model.set更新时间(new Timestamp(new Date().getTime()));
        itask基础设置Model.set更新账号(username);
        return itask基础设置Repository.save(itask基础设置Model);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void scClainClue (String permit, String username, String phone) throws Exception {
        List list = marketRepository.findImportListValidClue(permit, null, username, phone);
        if (list != null) {
            for (Object o : list) {
                Map map = (Map) o;
                if (!StringUtils.isNullOrBlank(map.get("导入编号"))) {
                    int importId = Integer.parseInt(map.get("导入编号").toString());
                    List<TDccDistributionLogModel> logModels = tDccDistributionLogRepository.getModelByImportId(importId);
                    //sc认领线索，删除可能存在的DCC分配的超时记录
                    tDccDistributionLogRepository.delete(logModels);
                }
            }
        }
    }

    @Override
    public void dccDistributionOverTimeHandling () throws Exception {
        List<TDccDistributionLogModel> logModels = tDccDistributionLogRepository.getOverTimeInfo();
        if (logModels != null) {
            List listModels = new ArrayList();
            for (TDccDistributionLogModel t : logModels) {
                List list = new ArrayList();
                Lsh导入名单Model lsh导入名单Model = lsh导入名单Repository.findOne(t.getImportId());
                if (lsh导入名单Model != null) {
                    logger.info("DCC分配线索，sc未认领，退回DCC信息，导入编号：" + lsh导入名单Model.get导入编号());
                    //推送消息给sc
                    String msg = MessageContext.getDCCDistributionClueOverTimeMessage(lsh导入名单Model.get顾客姓名());
                    LshMsgUtils.getLshMsg(lsh导入名单Model.get许可(), lsh导入名单Model.get所属CDO(), lsh导入名单Model.get许可(),
                            lsh导入名单Model.get所属销售顾问(), "线索", msg, lsh导入名单Model.get所属CDO(), lsh导入名单Model.get电话号码());

                    //极光推送
                    list.add(lsh导入名单Model.get所属销售顾问());
                    JsonObject jsonObject = JsonObjectUtils.getJsonObject("线索", null, null, lsh导入名单Model.get电话号码(), null, lsh导入名单Model.get所属销售顾问());
                    JPush.sendPushForAndroidAndIos(msg, msg, jsonObject, list, JPush.Platforms.iTask);
                    //将未被认领的线索返回给DCC，并标记该线索为 未认领线索；同时预约接待删除
                    List<Lsh待办事项Model> lsh待办事项Models = lsh待办事项Repository.findDCCOrder(lsh导入名单Model.get许可(), lsh导入名单Model.get所属销售顾问(), lsh导入名单Model.get导入编号());
                    if (lsh待办事项Models != null) {
                        for (Lsh待办事项Model lsh待办事项Model : lsh待办事项Models) {
                            lsh待办事项Model.set是否删除("是");
                        }
                        lsh待办事项Repository.save(lsh待办事项Models);
                    }
                    lsh导入名单Model.set所属销售顾问(null);
                    lsh导入名单Model.setClaimState("1");
                    listModels.add(lsh导入名单Model);
                }
                //删除超时记录
                tDccDistributionLogRepository.delete(t);
            }
            lsh导入名单Repository.save(listModels);
        }
    }
}
